package com.erpanderp.wam.ac.view.reimbursement;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.SwingWorker;

import org.primefaces.component.datatable.DataTable;
import org.primefaces.context.RequestContext;

import com.erpanderp.wam.ac.model.entity.reimbursement.Currency;
import com.erpanderp.wam.ac.model.entity.reimbursement.MiscExpense;
import com.erpanderp.wam.ac.model.entity.reimbursement.MiscExpenseDetails;
import com.erpanderp.wam.ac.model.service.reimbursement.MiscReimbursementDAO;
import com.erpanderp.wam.adm.model.entity.CustomLookup;
import com.erpanderp.wam.adm.model.entity.LookupValue;
import com.erpanderp.wam.adm.model.service.CustomLookupDAO;
import com.erpanderp.wam.usm.model.entity.user.Employee;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.usm.model.service.user.EmployeeDAO;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.EmailUtil;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMHostManager;


@ManagedBean
@ViewScoped
public class EditMiscReimbursementBean implements Serializable{

	
	private static final long serialVersionUID = 1L;
	private HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
	ServletContext context = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
	HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
	private WAMUser wamUser = (WAMUser) session.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);
	private TimeZone timeZone = TimeZone.getDefault();
	
	private MiscReimbursementDAO miscReimbursementDAO = new MiscReimbursementDAO();
	private EmployeeDAO employeeDAO = new EmployeeDAO();
	
	private MiscExpense miscExpense=new MiscExpense();
	private MiscExpenseDetails miscExpenseDetails = new MiscExpenseDetails();
	
	private List<MiscExpenseDetails> miscExpensesDetailsList = new ArrayList<MiscExpenseDetails>();
	private Map<String,String> currencyMap = new HashMap<String, String>();
	private CustomLookup customLookUp = new CustomLookup();
	private CustomLookupDAO customLookupDAO = new CustomLookupDAO();
	private List<LookupValue> lookUpValuesList = new ArrayList<LookupValue>();
	private List<Currency> Currencies  =  new ArrayList<Currency>();

	private String miscExpenseCode;
	private Employee employeeVP;
	private boolean COLLECTOR_FORM_VALID;
	private boolean FORM_VALID;
	private DataTable assignedMiscExpenseDetailsList;
	private EmailUtil emailUtil;
	private String EMAIL_MESSAGE;
	
	public EditMiscReimbursementBean() {
		miscExpenseCode = request.getParameter("miscExpenseCode");
		
		miscExpense = miscReimbursementDAO.getMiscExpense(miscExpenseCode);
		employeeVP = employeeDAO.getVP();
		
		miscExpensesDetailsList.addAll(miscExpense.getMiscExpensesDetails());
		
		customLookUp = customLookupDAO.getCustomLookUp(CommonLookup.CURRENCY_CUSTOM_LOOKUP);
		lookUpValuesList = customLookupDAO.getLookupValuesList(customLookUp.getCustomLookId());
		for(LookupValue lookUpValue : lookUpValuesList){
			currencyMap.put(lookUpValue.getLookupName(), lookUpValue.getLookupValue());
		}
		
		totalAmountandCurrencyList();
		
	}
	
	// Total Amount LIST & Currency
			public void totalAmountandCurrencyList() {
				for (LookupValue currency : lookUpValuesList) {
					for (MiscExpenseDetails miscExpenseDetails : miscExpensesDetailsList) {
						if (miscExpenseDetails.getCurrency().equals(
								currency.getLookupValue())) {
							// MATCHED = true;
							boolean ADDED = false;
							for (Currency cur : Currencies) {
								if (currency.getLookupValue().equals(cur.getCurrency())) {
									ADDED = true;
									// change the value
									cur.setAmount(cur.getAmount()
											+ miscExpenseDetails.getAmount());
									break;
								}
							}
							if (!ADDED) {
								// create new currentcy and add to the list
								Currency currencyObj = new Currency();
								currencyObj.setAmount(miscExpenseDetails
										.getAmount());
								currencyObj.setCurrency(miscExpenseDetails
										.getCurrency());
								Currencies.add(currencyObj);
							}
							// break;
						}
					}
				}
			}
	//REST BUTTON ACTIONS
	public void resetMiscExpenseDetailsAction(ActionEvent ae) {
		miscExpenseDetails.setBillDate(null);
		miscExpenseDetails.setBillDesc("");
		miscExpenseDetails.setBillNo("");
		miscExpenseDetails.setAmount(0.0f);
	}
	//ADD RECORDS TO LIST
	public void addMiscExpenseDetailsAction() {
		
		validateExpenseDetails();
		if (COLLECTOR_FORM_VALID) {
			
			try{
				//miscExpenseDetails.setEmployee(employee);
				miscExpenseDetails.setCreateDate(new Date());
				miscExpenseDetails.setCreatedBy(CommonLookup.CREATEDBY_DEVELOPER_TEXT);
				miscExpenseDetails.setStatus(CommonLookup.STATUS_ACTIVE);
					
				miscExpensesDetailsList.add(miscExpenseDetails); //ALL RECORDS LIST
				totalAmountandCurrencyListAction(miscExpenseDetails.getCurrency(),miscExpenseDetails.getAmount());
				
				miscExpenseDetails = new MiscExpenseDetails();
			
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	//REMOVE RECORDS FROM LIST
	public void removeMiscExpensesDetails(ActionEvent e) {
		MiscExpenseDetails selectedMiscExpenseDetails = (MiscExpenseDetails) assignedMiscExpenseDetailsList.getRowData();
		subtractTotalAmount(selectedMiscExpenseDetails.getCurrency(),selectedMiscExpenseDetails.getAmount());
		miscExpensesDetailsList.remove(selectedMiscExpenseDetails);
		
		miscReimbursementDAO.deleteMiscExpensDetailseById(selectedMiscExpenseDetails);
	}
	
	//ADDIGN CURRENCY TOTALS
	public void totalAmountandCurrencyListAction(String curncy,Float amt) {	 		
		try{
				boolean MATCHED = false;
				for(LookupValue currency : lookUpValuesList){					
					if(curncy.equals(currency.getLookupValue())){
						MATCHED = true;
						boolean ADDED = false;						
						for(Currency cur : Currencies){
							if(currency.getLookupValue().equals(cur.getCurrency())){
								ADDED = true;
								//change the value
								cur.setAmount(amt+ cur.getAmount());								
								break;
							}
						}						
						if(!ADDED ){
							//create new currentcy and add to the list
							Currency currencyObj = new Currency();
							currencyObj.setAmount(amt);
							currencyObj.setCurrency(curncy);
							Currencies.add(currencyObj);
						}						
						break;				
					}					
				}					
		 }catch (Exception e1) {
				e1.printStackTrace();
			}		
	}
			
	 //SUBTRACT CURRENCY
	 public void subtractTotalAmount(String curncy,Float amt) {	 		
		try{				
				for(LookupValue currency : lookUpValuesList){
					if(curncy.equals(currency.getLookupValue())){						
						for(Currency cur : Currencies){
							if(currency.getLookupValue().equals(cur.getCurrency())){								
								//change the value
								cur.setAmount(cur.getAmount() - amt);	
							}
						}										
					}					
				}					
			 }catch (Exception e1) {
					e1.printStackTrace();
			  }		
		}
	 
	 public String submitMiscExpense() {
			System.out.println("IN SUBMIT MISCEXPENSE");
			validate();
			if (FORM_VALID) {
				
				if (miscExpensesDetailsList.size() > 0) {
					//miscExpense.setEmployee(employee);
					miscExpense.setApprovedBy(employeeVP);
					miscExpense.setCreateDate(new Date());
					miscExpense.setCreatedBy(wamUser.getEmployee().getFirstName());
					miscExpense.setExpenseStatus(CommonLookup.MISC_INPROCESS_STATUS);
					miscExpense.getMiscExpensesDetails().addAll(miscExpensesDetailsList);
					
					miscReimbursementDAO.createMiscExpenseForm(miscExpense);
					

					 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,  " You have submitted successfully.", ""));
					
					
					//MAIL TRIGGERING CODE
						System.out.println("AT CALLER METHOD: " + sendMessage());  //*******DONT REMOVE*******
						
						miscExpensesDetailsList.clear();
						Currencies.clear();	
					    return "createmiscreimbursement";
				}
				return "createmiscreimbursement";
			}else{
				return null;
			}
			
		}
	 
	//SENDING EMAIL 
		public String sendMessage(){
					Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
					String domainName = context.getInitParameter("domainName");
								
					
					String approverMail="movvasravani89@gmail.com";		
					//String approverMail = travelRequest.getApprover().getEmail();
				
					emailUtil = new EmailUtil();
					if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {					
						String[] to = { employeeVP.getEmail() };
						emailUtil.setRecieverAddresses(to);
					}else{
						System.out.println("===========2222222222=============");
						String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
						System.out.println(to);
						emailUtil.setRecieverAddresses(to);
					}
							
					String requestURL = "ac/reimbursement/approvereimbursement.html?miscCode="
							+ miscExpense.getMiscExpenseCode()
							+ "&empId="
							+ wamUser.getEmployee().getEmployeeId();
					String privateLink = "http://" + hostsMap.get(CommonLookup.PRIVATEHOST) + "/" + domainName + "/" + requestURL;
					String publicLink = "http://" + hostsMap.get(CommonLookup.PUBLICHOST) + "/"	+ domainName + "/" + requestURL;
					
					String messageString = "Dear  " + employeeVP.getFirstName()
							+ "" + employeeVP.getLastName() + ",<br /><br />" +

							"<h3>New Misc. Expense  Details</h3>"
							+ "<table style='border: 1px solid #d9d9d9;'>"
							+ "<tr> <td>Employee Code </td><td> : </td><td>"
							+ wamUser.getEmployee().getEmployeeCode()
							+ " </td></tr>"
							+ "<tr> <td>Employee Name</td><td> : </td> <td>"
							+ wamUser.getEmployee().getFirstName() + " </td></tr>"
							+ "<tr> <td>Misc Expense Code</td><td> : </td> <td>"
							+ miscExpense.getMiscExpenseCode() + "</td></tr>" +

							"</table><br/>"
							+ "<a style='color:#FF9933;font-weight: bold;' href=\""
							+ privateLink + "\">"
							+ "Please click here to approve/reject expense form"
							+ "</a /><br />"
							+ "(Employees who are in Hyderabad office)"
							+ "<br /><br />"
							+ "<a style='color:#FF9933;font-weight: bold;' href=\""
							+ publicLink + "\">"
							+ "Please click here to approve/reject expense form"
							+ "</a /><br />" + "(out side Hyderabad office)"
							+ "<br /><br />" +

							"Thanks & Regards, <br />"
							+ CommonLookup.WAM_DEVTEAM_SIGNATURE;
					;
					
					emailUtil.setMessage(messageString);
					emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");
					emailUtil.setSubject(wamUser.getEmployee().getFirstName()+" "+wamUser.getEmployee().getLastName() +"( "+miscExpense.getMiscExpenseCode()+" ) -Misc. Expense Request");
					
					SwingWorker worker = new SwingWorker<String, Object>() {
						@Override
						protected String doInBackground() throws Exception {
							EMAIL_MESSAGE = emailUtil.processAndSendEmail();
							return null;
						}

						@Override
						protected void done() {
								System.out.println("DONE " + EMAIL_MESSAGE);		
						}
					};
					worker.execute();
					System.out.println( "BEFORE RETURNING: " + EMAIL_MESSAGE);
					return EMAIL_MESSAGE;
				}
	
	
	//VALIDATIONS 
	 
	 public void validate() {
			System.out.println("IN VALIDATE METHOD");
			
			FORM_VALID = true;
			if (ValidationUtil.isEmpty(miscExpense.getExpensePurpose(),
					"Purpose of expense", null, FacesContext.getCurrentInstance()) != null) {
				FORM_VALID = false;
			}
			if (ValidationUtil.isEmpty(miscExpense.getExpenseLocation(),
					"Location", null, FacesContext.getCurrentInstance()) != null) {
				FORM_VALID = false;
			}
			
			if (miscExpensesDetailsList.size() == 0) {
				FORM_VALID = false;
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_WARN,
								" Expense details can not be empty.", ""));
			}

		}
	public void validateExpenseDetails() {
		COLLECTOR_FORM_VALID = true;
		if (ValidationUtil.isEmpty(
				miscExpenseDetails.getBillDate() != null ? miscExpenseDetails
						.getBillDate().toString() : null, "Bill date", null,
				FacesContext.getCurrentInstance()) != null) {
			COLLECTOR_FORM_VALID = false;
		}
		if (ValidationUtil.isEmpty(miscExpenseDetails.getBillDesc(),
				"Bill description", null, FacesContext.getCurrentInstance()) != null) {
			COLLECTOR_FORM_VALID = false;
		}
		if(miscExpenseDetails.getAmount() == 0){
			COLLECTOR_FORM_VALID = false;
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(FacesMessage.SEVERITY_WARN,"Expense amount should not zero.", ""));
		}
		if(miscExpenseDetails.getAmount() < 0){
			COLLECTOR_FORM_VALID = false;
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(FacesMessage.SEVERITY_WARN,"Expense amount should be grater than zero.", ""));
			miscExpenseDetails.setAmount(0.0f);
		}	
	}

	 public void confirmationAction(ActionEvent e){
		 validate();
 		
 		if(FORM_VALID){
			RequestContext.getCurrentInstance().execute("confirmation.show();");
		}else{
			RequestContext.getCurrentInstance().execute("confirmation.hide();");
		}
    }	
	
	//GETTERS AND SETTERS
	public String getMiscExpenseCode() {
		return miscExpenseCode;
	}

	public void setMiscExpenseCode(String miscExpenseCode) {
		this.miscExpenseCode = miscExpenseCode;
	}


	public MiscReimbursementDAO getMiscReimbursementDAO() {
		return miscReimbursementDAO;
	}


	public void setMiscReimbursementDAO(MiscReimbursementDAO miscReimbursementDAO) {
		this.miscReimbursementDAO = miscReimbursementDAO;
	}


	public MiscExpense getMiscExpense() {
		return miscExpense;
	}


	public void setMiscExpense(MiscExpense miscExpense) {
		this.miscExpense = miscExpense;
	}


	public Employee getEmployeeVP() {
		return employeeVP;
	}


	public void setEmployeeVP(Employee employeeVP) {
		this.employeeVP = employeeVP;
	}


	public List<MiscExpenseDetails> getMiscExpensesDetailsList() {
		return miscExpensesDetailsList;
	}


	public void setMiscExpensesDetailsList(List<MiscExpenseDetails> miscExpensesDetailsList) {
		this.miscExpensesDetailsList = miscExpensesDetailsList;
	}


	public MiscExpenseDetails getMiscExpenseDetails() {
		return miscExpenseDetails;
	}


	public void setMiscExpenseDetails(MiscExpenseDetails miscExpenseDetails) {
		this.miscExpenseDetails = miscExpenseDetails;
	}


	public Map<String,String> getCurrencyMap() {
		return currencyMap;
	}


	public void setCurrencyMap(Map<String,String> currencyMap) {
		this.currencyMap = currencyMap;
	}


	public CustomLookup getCustomLookUp() {
		return customLookUp;
	}


	public void setCustomLookUp(CustomLookup customLookUp) {
		this.customLookUp = customLookUp;
	}


	public CustomLookupDAO getCustomLookupDAO() {
		return customLookupDAO;
	}


	public void setCustomLookupDAO(CustomLookupDAO customLookupDAO) {
		this.customLookupDAO = customLookupDAO;
	}


	public List<LookupValue> getLookUpValuesList() {
		return lookUpValuesList;
	}


	public void setLookUpValuesList(List<LookupValue> lookUpValuesList) {
		this.lookUpValuesList = lookUpValuesList;
	}


	public List<Currency> getCurrencies() {
		return Currencies;
	}


	public void setCurrencies(List<Currency> currencies) {
		Currencies = currencies;
	}

	public DataTable getAssignedMiscExpenseDetailsList() {
		return assignedMiscExpenseDetailsList;
	}

	public void setAssignedMiscExpenseDetailsList(
			DataTable assignedMiscExpenseDetailsList) {
		this.assignedMiscExpenseDetailsList = assignedMiscExpenseDetailsList;
	}

	public TimeZone getTimeZone() {
		return timeZone;
	}

	public void setTimeZone(TimeZone timeZone) {
		this.timeZone = timeZone;
	}

}
